var DsModule = {
    root: window.root == null ? "/" : window.root,
    modulePath: "/", //公共的模块路径
    vars: {},//全局变量
    loadCss: false,
    cacheCss: [],
    cacheHtml: [],
    cacheJs: [],
    importJs: [],//是否已经引入过js
    moduleId: {}, //id 对应模块
    handlers: {},//路径处理器
    controller: [],
    ieVersion: null,
    protocolFile: false,
    defaultEvent:[],//默认事件绑定,
    currentHash:null,
    clickListener:function(_this){
        return function(e){
            var element=e.target;
            var classNames = element.className.split(' ');
            for(var i=0;i<classNames.length;i++){
                if(DsModule.defaultEvent[classNames[i]]!=null){
                    DsModule.defaultEvent[classNames[i]](element,_this);
                }
            }
        }
    },
    init: function () {
        DsModule.currentHash=window.location.hash;
        //开启hash路径监听
        if (window.location.protocol == "file:") {
            DsModule.protocolFile = true;
        }
        var browser = navigator.appName;
        var b_version = navigator.appVersion;
        var version = b_version.split(";");
        var trim_Version = version[1].replace(/[ ]/g, "");
        if (browser == "Microsoft Internet Explorer" && trim_Version == "MSIE6.0") {
            DsModule.ieVersion = 6;
        } else if (browser == "Microsoft Internet Explorer" && trim_Version == "MSIE7.0") {
            DsModule.ieVersion = 7;
        } else if (browser == "Microsoft Internet Explorer" && trim_Version == "MSIE8.0") {
            DsModule.ieVersion = 8;
        }
        if (!document.getElementsByClassName) {
            document.getElementsByClassName = function (className, element) {
                var children = (element || document).getElementsByTagName('*');
                var elements = [];
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    var classNames = child.className.split(' ');
                    for (var j = 0; j < classNames.length; j++) {
                        if (classNames[j] == className) {
                            elements.push(child);
                            break;
                        }
                    }
                }
                return elements;
            };
        }
    },
    _getResUrl: function (url) {
        if (url.indexOf("http://") == 0) {
            return url;
        }
        if (url.indexOf("https://") == 0) {
            return url;
        }
        if (DsModule.protocolFile) {
            if (DsModule.root) {
                var hrefStr = window.location.href;
                hrefStr = hrefStr.substring(0, hrefStr.lastIndexOf(DsModule.root));
                return hrefStr + DsModule.root + url.substring(1,url.length);
            }
            return url;
        }
        if (!DsModule.root) {
            return url;
        }
        return DsModule.root + url;

    },
    _getRequest: function () {
        var xmlHttp = null;
        try {
            xmlHttp = new XMLHttpRequest();
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    console.error(e);
                }
            }
        }
        return xmlHttp;
    },
    resIndex: 0
    ,
    _getRes: function (url, callback) {
        if(DsModule.protocolFile){
            //本地文件暂时无法跨域加载
            return;
        }
        var xmlHttp = DsModule._getRequest();
        xmlHttp.open("GET", url, true);
        xmlHttp.setRequestHeader("Content-Type", "text/html");
        xmlHttp.onreadystatechange = function () {
            if ((xmlHttp.readyState == 4) && (xmlHttp.status == 200)) {
                callback(xmlHttp.responseText);
            }
        };
        xmlHttp.send(null);
    },
    _getModuleHtml: function (moduleName, html) {
        var index = html.indexOf("{{#" + moduleName + "}}") + 5 + moduleName.length;
        var endIndex = html.indexOf("{{/" + moduleName + "}}");
        var str = html.substring(index, endIndex);
        if (str == null) {
            throw new Error(moduleName + "：不存在当前资源文件中");
        }
        return str;
    },
    _stringToChildNodes: function (txt) {
        var objE = document.createElement("div");
        objE.innerHTML = txt;
        return objE;
    },
    handler: function (key, callback) {
        DsModule.handlers[key] = callback;
    },
    getParams: function (paramsStr) {
        var params = {};
        var strs = paramsStr.split("&");
        for (var i = 0; i < strs.length; i++) {
            params[strs[i].split("=")[0]] = decodeURIComponent(strs[i].split("=")[1]);
        }
        return params;
    },
    paramsToUrl: function (obj) {
        if (obj == null) {
            return "";
        }
        var paramsStr = "";
        var joinStr = "";
        for (var k in obj) {
            paramsStr += joinStr + k + "=" + encodeURIComponent(obj[k]);
            if (joinStr == "") {
                joinStr = "&";
            }
        }
        return paramsStr;
    },


    /**
     * 可刷新，可跳转
     * @param url 不传值为刷新
     * @param obj
     */
    to: function (url, obj,reload) {
        if (url != null) {
            var params = "";
            if(obj!=null){
                for (var k in obj) {
                    params += "&" + k + "=" + obj[k];
                }
            }
            if(params!=""){
                if (url.indexOf("?") != -1) {
                    url += params;
                } else {
                    url += "?" + params.substring(1, params.length);
                }
            }
            window.location.hash = url;
        }
        if (DsModule.handlers[url] != null) {
            DsModule.handlers[url](reload);
        } else {
            DsModule.toDefaultIndex(reload);
        }
    },

    /**
     * 获取路径和参数
     */
    getPath:function(){
        var hash = window.location.hash;
        if (hash == "") {
            return;
        }
        var path = hash.substring(1, hash.length);
        var paramsStr="";
        if (hash.indexOf("?") != -1) {
            path=hash.substring(1, hash.indexOf("?"));
            paramsStr = hash.substring(hash.indexOf("?")+1, hash.length);
        }
        var params = DsModule.getParams(paramsStr);
        return {"path":path,"params":params};
    },
    toDefaultIndex: function (reload) {
        var obj=DsModule.getPath();
        document.body.innerHTML = "";
        var m = new Module(obj.path);
        m.params = obj.params;
        m.load();
    }
    ,
    getModule: function (id) {
        return DsModule.moduleId[id];
    }
};
DsModule.init();


//跳转默认事件 hash 跳转地址  参数前缀 data-=""
DsModule.defaultEvent["e-go"]=function(obj){
    var url=obj.getAttribute("href");
    var reload=obj.getAttribute("reload");
    if(reload==null){
        reload=false;
    }else{
        reload=true;
    }
    var ab= obj.attributes;
    var param={};
    for(var i=0;i<ab.length;i++){
        var k=ab[i];
        if(k.name.startsWith("data-")){
            param[k.name.substring(5,k.name.length)]=k.value;
        }
    }
    DsModule.to(url,param,reload);
}

//跳转到当前模块的主页 index
DsModule.defaultEvent["e-go-index"]=function(obj,_this){
    var hash = window.location.hash;
    var reload=obj.getAttribute("reload");
    if(reload==null){
        reload=false;
    }else{
        reload=true;
    }
    var url="";
    hash = hash.substring(1, hash.length);
    if(hash.indexOf("/")==-1){
        url+="/index";
    }else{
        url=hash.substring(0,hash.lastIndexOf("/"))+"/index";
    }
    var ab= obj.attributes;
    var param={};
    for(var i=0;i<ab.length;i++){
        var k=ab[i];
        if(k.name.startsWith("data-")){
            param[k.name.substring(5,k.name.length)]=k.value;
        }
    }
    DsModule.to(url,param,reload);
}







/**
 * js 执行在html中
 * @type {{exec: DsTemplate.exec}}
 */
var DsTemplate = {
    exec: function (html, data) {
        if (html == null) {
            return "";
        }
        if (data == null) {
            data = {};
        }
        html = html.replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/<js-code>/g, "<js>{</js>").replace(/<\/js-code>/g, "<js>}</js>");
        html = html.replace(/<\/js>/g, "\n<\/js>\n").replace(/<js>/g, "\n<js>\n");
        var htmls = html.split("\n");
        var resultHtml1 = null;
        var resultHtml = "var resultHtml1=\"\";\n";
        var jsFlag = false;
        for (var i = 0; i < htmls.length; i++) {
            var htmlData = htmls[i];
            if (htmlData.trim() == "") {
                continue;
            }
            if (htmlData.trim().indexOf('<js>') != -1) {
                jsFlag = true;
                continue;
            } else if (htmlData.trim().indexOf('</js>') != -1) {
                jsFlag = false;
                continue;
            }
            if (jsFlag) {
                resultHtml += htmlData + "\n";
            } else {
                htmlData = htmlData.replace(/\r/g, "").replace(/"/g, "\\\"").replace(/'/g, "\\\'");
                resultHtml += "resultHtml1+=\"" + htmlData + "\";\n";
            }
        }
        var regNotStart2 = /\$\{[A-Za-z0-9\.@\s_\[\]]+}/g;
        var match2 = resultHtml.match(regNotStart2);
        if (match2 != null) {
            for (var i = 0; i < match2.length; i++) {
                resultHtml = resultHtml.replace(match2[i], ("\"+DsTemplate.format(" + match2[i].substring(2, match2[i].length - 1) + ")+\""));
                while (resultHtml.indexOf(match2[i]) != -1) {
                    resultHtml = resultHtml.replace(match2[i], ("\"+DsTemplate.format(" + match2[i].substring(2, match2[i].length - 1) + ")+\""));
                }
            }
        }
        eval(resultHtml);
        return resultHtml1;
    },
    format: function (data) {
        if (data!=null) {
            return data;
        }
        return "";
    }
};

/**
 * 模块定义加载
 * @param moduleName
 * @constructor
 */
var Module = function (modulePath) {
    if (modulePath == null) {
        throw new Error("模块路径不能为空");
    }
    this.modulePath = DsModule.modulePath + modulePath;
    this.baseUrl = this.modulePath.substring(0, this.modulePath.lastIndexOf("/"));
    this.moduleName = this.modulePath.substring(this.modulePath.lastIndexOf("/") + 1, this.modulePath.length); //模块下面子模块
    this.resultHtml = null;
    this.isLoadJs = true;//默认加载对应的js
    this.resHtmlUrl = this.baseUrl + "/module.html"; //资源html 路径
    this.resJsUrl = this.baseUrl + "/" + this.moduleName + ".js"; //资源js 路径
    this.data = {};//数据
    this.params = {};//url数据参数
    this.parentDom = null; //父级dom元素
    this.selfDom = null;//本元素dom
    this.resLoadSum = -1;// 资源加载总数
    this.resLoadCount = 0;// 资源加载数量
    this.importSum = -1;//依赖资源总数
    this.importCount = 0;//依赖加载数量
    this.id = null;
    this.stopFun = false;
    this.loadCount = 0;//已经加载次数
    this.loadCompleteFun = [];//加载完成后执行的事件
};

/**
 * 有依赖调用
 * @private
 */
Module.prototype._callJsObj = function () {
    if (this.import == null) {
        this._import([]);
    } else {
        this._import(this.import);
    }
}
/**
 * 把模块加载到父元素
 */
Module.prototype.load = function (obj) {
    var _this = this;
    if (obj != null) {
        if(typeof (obj)=='string'){
            var id=obj;
            _this.parentDom = document.getElementById(id);
            DsModule.moduleId[id] = this;
            _this.id = id;
        }
    } else {
        _this.parentDom = document.body;
    }
    _this._load();
    return this;
};
/**
 * 计算依赖的文件数量
 * @param obj
 */
Module.prototype._eachImportCount = function (obj) {
    this.importSum++;
    if (obj.import != null) {
        for (var i = 0; i < obj.import.length; i++) {
            this._eachImportCount(obj.import[i]);
        }
    }
};

/**
 * jquery 对象只在当面模块生效
 * @param obj
 * @returns {jQuery}
 */
Module.prototype.$ = function (obj) {
    return obj==null? $(this.selfDom):$(this.selfDom).find(obj);
};

/**
 *循环导入依赖
 */
Module.prototype._eachImport = function (obj) {
    var _this = this;
    var callback = function () {
        _this.importCount++;
        if (_this.importSum == _this.importCount) {
            if (_this.before != null) {
                var flag =_this.before.call(_this);
                if(flag==false){
                    return;
                }
            }
            if (_this.stopFun) {
                return;
            }
            _this.selfDom = DsModule._stringToChildNodes(DsTemplate.exec(_this.resultHtml, _this.data));
            _this.parentDom.appendChild(_this.selfDom);
            _this.loadComplete();
            if (_this.after != null) {
                _this.after.call(_this);
            }
            _this.selfDom.removeEventListener('click',DsModule.clickListener(_this));
            _this.selfDom.addEventListener('click',DsModule.clickListener(_this))

        }
    };
    var resArrayUrl = obj.url;
    if (resArrayUrl.lastIndexOf(".css") != -1) {
        this._loadCssRes(resArrayUrl, function () {
            if (obj.import != null) {
                for (var i = 0; i < obj.import.length; i++) {
                    this._eachImport(obj.import[i]);
                }
            }
            callback();
        });
    } else if (resArrayUrl.lastIndexOf(".js") != -1) {
        this.improtJs(resArrayUrl, function () {
            if (obj.import != null) {
                for (var i = 0; i < obj.import.length; i++) {
                    this._eachImport(obj.import[i]);
                }
            }
            callback();
        });
    }


};
/**
 * 引入依赖文件
 * @param resArray
 * @private
 */
Module.prototype._import = function (resArray) {
    var _this = this;
    _this.importSum = 0;
    for (var i = 0; i < resArray.length; i++) {
        _this._eachImportCount(resArray[i]);
    }
    if (_this.importSum == _this.importCount) {
        if (_this.before != null) {
            var flag =_this.before.call(_this);
            if(flag==false){
                return;
            }
        }
        if (_this.stopFun) {
            return;
        }
        _this.selfDom = DsModule._stringToChildNodes(DsTemplate.exec(_this.resultHtml, _this.data));
        _this.parentDom.appendChild(_this.selfDom);
        _this.loadComplete();
        if (_this.after != null) {
            _this.after.call(_this);
        }
        _this.selfDom.removeEventListener('click',DsModule.clickListener(_this));
        _this.selfDom.addEventListener('click',DsModule.clickListener(_this))
        return;
    }
    for (var i = 0; i < resArray.length; i++) {
        _this._eachImport(resArray[i]);
    }
};

/**
 * 开始加载模块资源
 * @private
 */
Module.prototype._load = function () {
    var _this = this;
    var callback = function () {
        _this.resLoadCount++;
        if (_this.resLoadSum == _this.resLoadCount) {
            _this._callJsObj.call(_this);
        }
    };
    _this.resLoadSum = 2;
    _this._loadJsRes(this.resJsUrl, callback); //模块内的js使用文本方式获取
    _this._loadHtmlRes(this.resHtmlUrl, callback);
};

/**
 * 加载css文件
 * @param url
 * @param callback
 * @private
 */
Module.prototype._loadCssRes = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.cacheCss[url] != null) {
        callback.call(_this);
        return;
    }
    var link = document.createElement("link");
    link.type = "text/css";
    link.rel = "stylesheet";
    link.onload = function () {
        DsModule.cacheCss[url] = true;
        callback.call(_this);
    };
    link.href = url;
    document.getElementsByTagName("head")[0].appendChild(link);
};

/**
 * 引入js文件
 * @param url
 * @param callback
 */
Module.prototype.improtJs = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.importJs[url] != null) {
        callback.call(_this);
        return;
    }
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    if (DsModule.ieVersion != null && DsModule.ieVersion <= 8) {
        script.onreadystatechange = function () {
            DsModule.importJs[url] = true;
            callback.call(_this);
        };
    } else {
        script.onload = function () {
            DsModule.importJs[url] = true;
            callback.call(_this);
        };
    }
    head.appendChild(script);
};
/**
 * 加载html 文件
 * @param url
 * @param callback
 * @private
 */
Module.prototype._loadHtmlRes = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.cacheHtml[url] != null) {
        _this.resultHtml = DsModule._getModuleHtml(_this.moduleName, DsModule.cacheHtml[url]);
        callback.call(_this);
        return;
    }
    DsModule._getRes(url, function (data) {
        DsModule.cacheHtml[url] = data;
        _this.resultHtml = DsModule._getModuleHtml(_this.moduleName, data);
        callback.call(_this);
    });
};

/**
 * 加载js 文件
 * @param url
 * @param callback
 * @private
 */
Module.prototype._loadJsRes = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.cacheJs[url] != null) {
        var jsObj = eval("0," + DsModule.cacheJs[url]).call(_this);
        for (var key in jsObj) {
            _this[key] = jsObj[key];
        }
        callback.call(_this);
        return;
    }
    DsModule._getRes(url, function (data) {
        DsModule.cacheJs[url] = data;
        var jsObj = eval("0," + data).call(_this);
        for (var key in jsObj) {
            _this[key] = jsObj[key];
        }
        callback.call(_this);
    });
};

/**
 * 因为有异步请求数据导致模块加载需要中断
 */
Module.prototype.stop = function () {
    this.stopFun = true;
};

/**
 * 继续执行
 */
Module.prototype.continue = function () {
    this.stopFun = false;
    this._reloadData();
};


/**
 * 重新加载模块，不包含数据
 * @param data
 */
Module.prototype.reloadData = function (data) {
    var _this = this;
    var reloadData = function () {
        if (data != null) {
            for(var k in data){
                _this.data[k] = data[k];
            }
        }
        _this.remove();
        _this.selfDom = DsModule._stringToChildNodes(DsTemplate.exec(_this.resultHtml, _this.data));
        _this.parentDom.appendChild(_this.selfDom);
        DsModule.moduleId[_this.id] = _this;
        _this.loadComplete();
        if (_this.after != null) {
            _this.after.call(_this);
        }
        //默认事件加载
        _this.selfDom.removeEventListener('click',DsModule.clickListener(_this));
        _this.selfDom.addEventListener('click',DsModule.clickListener(_this))
    }
    if (_this.isLoadComplete()) {
        reloadData();
        return;
    }
    _this.loadCompleteFun.push(reloadData);
};

Module.prototype._reloadData = function (data) {
    var _this = this;
    var reloadData = function () {
        if (data != null) {
            for(var k in data){
                _this.data[k] = data[k];
            }
        }
        _this.remove();
        _this.selfDom = DsModule._stringToChildNodes(DsTemplate.exec(_this.resultHtml, _this.data));
        _this.parentDom.appendChild(_this.selfDom);
        DsModule.moduleId[_this.id] = _this;
        _this.loadComplete();
        if (_this.after != null) {
            _this.after.call(_this);
        }
        //默认事件加载
        _this.selfDom.removeEventListener('click',DsModule.clickListener(_this));
        _this.selfDom.addEventListener('click',DsModule.clickListener(_this))
    }
    reloadData();
};

/**
 * 重新加载模块，包括数据
 */
Module.prototype.reload = function (data) {
    var _this = this;
    var reload = function () {
        if (data != null) {
            _this.data = data;
        }
        if (_this.before != null) {
            var flag =_this.before.call(_this);
            if(flag==false){
                return;
            }
        }
        if (_this.stopFun) {
            return;
        }
        _this.remove();
        _this.selfDom = DsModule._stringToChildNodes(DsTemplate.exec(_this.resultHtml, _this.data));
        _this.parentDom.appendChild(_this.selfDom);
        DsModule.moduleId[_this.id] = _this;
        _this.loadComplete();
        if (_this.after != null) {
            _this.after.call(_this);
        }
        _this.selfDom.removeEventListener('click',DsModule.clickListener(_this));
        _this.selfDom.addEventListener('click',DsModule.clickListener(_this))
    }
    if (_this.isLoadComplete()) {
        reload();
        return;
    }
    _this.loadCompleteFun.push(reload);

};

/**
 * 删除自己
 */
Module.prototype.remove = function () {
    DsModule.moduleId[this.id] = null;
    if (this.selfDom != null) {
        this.parentDom.removeChild(this.selfDom);
    }
};

/**
 * 表单转成键值对
 * @param className
 * @returns {{}}
 */
Module.prototype.toMap = function (className) {
    var data = {};
    this.$(className).each(function () {
        if($(this).attr("type")=="checkbox"){
            data[$(this).attr("name")] = $(this).is(':checked');
        }else{
            data[$(this).attr("name")] = $(this).val();
        }
    });
    return data;
};

/**
 * 加载到页面后
 */
Module.prototype.loadComplete = function () {
    this.loadCount++;
    while (this.loadCompleteFun.length > 0) {
        var deleteFun=this.loadCompleteFun[0];
        this.loadCompleteFun.splice(0, 1);
        deleteFun();
    }
}


/**
 * 是否加载完成
 */
Module.prototype.isLoadComplete = function () {
    if (this.loadCount > 0) {
        return true;
    }
    return false;
};



